package com.xwj.service.impl;

import com.xwj.dao.UserAccountMapper;
import com.xwj.dao.UserAccountRecordMapper;
import com.xwj.domain.UserAccount;
import com.xwj.domain.UserAccountRecord;
import com.xwj.dto.UserAccountDto;
import com.xwj.service.ZookeeperLockService;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * @author xwj
 * @date 2020/5/6
 */
@Service
public class ZookeeperLockServiceImpl implements ZookeeperLockService {
    private static Logger logger = LoggerFactory.getLogger(ZookeeperLockServiceImpl.class);
    @Autowired
    private CuratorFramework client;
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private UserAccountRecordMapper userAccountRecordMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void takeMoneyZookeeperLock(UserAccountDto dto) throws Exception {
        final String path = "/distribute/lock";
        InterProcessMutex mutex = new InterProcessMutex(client, path);
        try {
            if (mutex.acquire(10L, TimeUnit.SECONDS)) {
                UserAccount userAccount = userAccountMapper.selectByUserId(dto.getUserId());
                if (userAccount != null) {
                    // 余额足够
                    if (userAccount.getAmount().compareTo(dto.getAmount()) >= 0) {
                        // 更新余额
                        userAccountMapper.updateAmount(dto.getAmount(), userAccount.getId());
                        // 记录
                        UserAccountRecord userAccountRecord = new UserAccountRecord();
                        userAccountRecord.setCreateTime(LocalDateTime.now());
                        userAccountRecord.setAccountId(userAccount.getId());
                        userAccountRecord.setMoney(dto.getAmount());
                        userAccountRecordMapper.insertSelective(userAccountRecord);
                        logger.info("用户：{}，本次提现：{}，当前余额：{}", dto.getUserId(), dto.getAmount(), userAccount.getAmount());
                    } else {
                        throw new Exception("账户余额不足");
                    }
                } else {
                    throw new Exception("账户不存在");
                }
            }
        } catch (Exception e) {
            throw e;
        } finally {
            try {
                mutex.release();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
